package com.polaris.live.floating

import android.animation.Animator
import android.animation.ValueAnimator
import android.view.MotionEvent
import android.view.View
import android.view.WindowManager
import com.blankj.utilcode.util.BarUtils
import com.blankj.utilcode.util.ScreenUtils
import com.polaris.live.common.cacha.CacheUtil
import com.polaris.live.common.ext.autoDp
import kotlin.math.abs

/**
 * FloatingViewTouchListener
 * @author Created by 天晴 on 2024/11/20 20:21
 * @since 1.0.0
 **/
class FloatingViewTouchListener(
    private val wl: WindowManager.LayoutParams,
    private val windowManager: WindowManager,
    private var singleClickListener: () -> Unit,
    private var changeType: (type: Int) -> Unit,
) : View.OnTouchListener {
    private var oneX = 0
    private var oneY = 0
    private var lastX = 0
    private var lastY = 0
    private var lastTime = 0L
    private var screenWidth = 0
    private var screenHeight = 0
    private var mOrientation = 0
    private var mType = 0  //0正常  1左缩小  2 右缩小

    init {
        screenWidth = ScreenUtils.getAppScreenWidth()
        screenHeight = ScreenUtils.getAppScreenHeight()
    }

    override fun onTouch(view: View, motionEvent: MotionEvent): Boolean {
        when (motionEvent.action) {
            MotionEvent.ACTION_DOWN -> {
                cancelAnimator()
                oneX = motionEvent.rawX.toInt()
                oneY = motionEvent.rawY.toInt()
                lastX = motionEvent.rawX.toInt()
                lastY = motionEvent.rawY.toInt()
                lastTime = System.currentTimeMillis()
            }

            MotionEvent.ACTION_MOVE -> {
                val nowX = motionEvent.rawX.toInt()
                val nowY = motionEvent.rawY.toInt()
                val movedX = nowX - lastX
                val movedY = nowY - lastY
                lastX = nowX
                lastY = nowY
                var wx = wl.x + movedX
                var wy = wl.y + movedY
                if (mType == 0) {
                    when {
                        wx > screenWidth - view.width * 0.7 -> {
                            mType = 2
                            changeType.invoke(mType)
                        }
                        wx < -view.width * 0.3 -> {
                            mType = 1
                            changeType.invoke(mType)
                        }
                    }
                }
                val maxHeight = if (mOrientation == 0) {
                    screenHeight - 67.autoDp
                } else {
                    screenHeight - 67.autoDp - BarUtils.getStatusBarHeight()
                }
                wy = wy.coerceIn(0, maxHeight)
                when (mType) {
                    0 -> {
                        wl.x = wx
                        wl.y = wy
                    }
                    1 -> {
                        wl.x = 0
                        wl.y = wy
                    }
                    2 -> {
                        wl.x = screenWidth - 22.autoDp
                        wl.y = wy
                    }
                }
                windowManager.updateViewLayout(view, wl)
                CacheUtil.saveFloatingViewAddr(wl.x, wl.y)
            }

            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                val nowX = motionEvent.rawX.toInt()
                val nowY = motionEvent.rawY.toInt()
                // 判断是否为点击事件
                val isClick = abs(oneX - nowX) < 10 && abs(oneY - nowY) < 10 && System.currentTimeMillis() - lastTime < 200
                if (isClick) {
                    if (mType != 0) {
                        changeType.invoke(0)
                        val nx = when (mType) {
                            1 -> {
                                wl.x = 0
                                0
                            }
                            2 -> {
                                val newX = screenWidth - 56.autoDp
                                wl.x = newX
                                newX
                            }
                            else -> 0
                        }
                        wl.y = wl.y
                        windowManager.updateViewLayout(view, wl)
                        CacheUtil.saveFloatingViewAddr(nx, wl.y)
                        mType = 0
                    } else {
                        singleClickListener.invoke()
                    }
                } else {
                    if (mType == 0) {
                        startAnimator(view)
                    }
                }
            }

            else -> {

            }
        }
        return false
    }

    var animator: ValueAnimator? = null
    private fun startAnimator(view: View) {
        val endX = if (wl.x > screenWidth / 2) {
            screenWidth - view.width
        } else {
            0
        }
        animator = ValueAnimator.ofInt(wl.x, endX)
        animator?.duration = 200
        animator?.addUpdateListener { animation ->
            val value = animation.animatedValue as Int
            wl.apply {
                x = value
            }
            //更新悬浮球控件位置
            windowManager.updateViewLayout(view, wl)
            CacheUtil.saveFloatingViewAddr(value, wl.y)
        }
        animator?.start()
        animator?.addListener(object : Animator.AnimatorListener {
            override fun onAnimationStart(animation: Animator) {
            }

            override fun onAnimationEnd(animation: Animator) {
                animator = null
            }

            override fun onAnimationCancel(animation: Animator) {
            }

            override fun onAnimationRepeat(animation: Animator) {
            }

        })
    }

    private fun cancelAnimator() {
        animator?.cancel()
        animator = null
    }

    /**
     * 更新显示方向 0竖向  1横向
     */
    fun updataOrientation(view: View, orientation: Int) {
        if (mOrientation == orientation) return
        mOrientation = orientation
        val sw = ScreenUtils.getAppScreenWidth()
        val sh = ScreenUtils.getAppScreenHeight()
        screenWidth = if (orientation == 0) minOf(sw, sh) else maxOf(sw, sh)
        screenHeight = if (orientation == 0) maxOf(sw, sh) else minOf(sw, sh)
        val wx = if (mType != 0) screenWidth - 22.autoDp else screenWidth - 56.autoDp
        val maxHeight = screenHeight - 67.autoDp - if (orientation == 1) BarUtils.getStatusBarHeight() else 0
        val wy = minOf(wl.y, maxHeight)
        wl.apply {
            x = wx
            y = wy
        }
        windowManager.updateViewLayout(view, wl)
        CacheUtil.saveFloatingViewAddr(wx, wy)
    }

}
